package org.javahispano.javacup.tacticas.tacticas_aceptadas.diversion;

/*
 * Licence: To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
import org.javahispano.javacup.modelo.engine.SituacionPartido;
import org.javahispano.javacup.modelo.util.Posicion;
import org.javahispano.javacup.modelo.util.Constantes;
import org.javahispano.javacup.modelo.TacticaDetalle;
import org.javahispano.javacup.modelo.JugadorDetalle;
import org.javahispano.javacup.modelo.Tactica;
import org.javahispano.javacup.modelo.comando.Comando;
import org.javahispano.javacup.modelo.comando.ComandoIrA;
import org.javahispano.javacup.modelo.comando.ComandoGolpearBalon;
import org.javahispano.javacup.render.EstiloUniforme;
import java.util.*;
import java.awt.Color;
import org.javahispano.javacup.modelo.*;

/**
 *
 * @author carlos
 */
public class TacticaDiversion implements Tactica {
    LinkedList<Comando> comandos = new LinkedList<Comando>();

    Posicion alineacion1[]=new Posicion[]{
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(-21.874125874125873,-30.407239819004527),
        new Posicion(-0.7132867132867133,-35.15837104072398),
        new Posicion(19.25874125874126,-26.84389140271493),
        new Posicion(13.314685314685315,-7.601809954751132),
        new Posicion(-17.356643356643357,-7.839366515837104),
        new Posicion(-1.6643356643356644,-19.2420814479638),
        new Posicion(17.11888111888112,14.015837104072398),
        new Posicion(-17.594405594405593,30.6447963800905),
        new Posicion(0.0,23.993212669683256),
        new Posicion(16.88111888111888,30.6447963800905)
    };



    Posicion alineacion2[]=new Posicion[]{
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(-11.16030534351145,-31.082089552238806),
        new Posicion(11.16030534351145,-31.6044776119403),
        new Posicion(27.251908396946565,-27.94776119402985),
        new Posicion(-29.84732824427481,-26.902985074626866),
        new Posicion(8.564885496183205,-7.574626865671642),
        new Posicion(-10.641221374045802,-7.052238805970149),
        new Posicion(27.251908396946565,4.440298507462686),
        new Posicion(-29.32824427480916,3.3955223880597014),
        new Posicion(-0.2595419847328244,19.067164179104477),
        new Posicion(-0.2595419847328244,35.78358208955224)
    };

    Posicion alineacion3[]=new Posicion[]{
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(-11.16030534351145,-31.082089552238806),
        new Posicion(11.16030534351145,-31.6044776119403),
        new Posicion(26.732824427480914,-20.111940298507463),
        new Posicion(-29.32824427480916,-21.67910447761194),
        new Posicion(0.2595419847328244,-0.26119402985074625),
        new Posicion(-18.946564885496183,-0.26119402985074625),
        new Posicion(18.946564885496183,-0.26119402985074625),
        new Posicion(-19.46564885496183,35.78358208955224),
        new Posicion(-0.2595419847328244,19.067164179104477),
        new Posicion(18.946564885496183,35.26119402985075)
    };

    Posicion alineacion4[]=new Posicion[]{
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(-11.16030534351145,-31.082089552238806),
        new Posicion(11.16030534351145,-31.6044776119403),
        new Posicion(28.290076335877863,-28.470149253731343),
        new Posicion(-28.290076335877863,-28.470149253731343),
        new Posicion(11.16030534351145,-1.3059701492537314),
        new Posicion(-10.641221374045802,-0.7835820895522387),
        new Posicion(-27.251908396946565,31.6044776119403),
        new Posicion(-10.641221374045802,30.559701492537314),
        new Posicion(9.603053435114505,28.992537313432837),
        new Posicion(25.69465648854962,28.992537313432837)
    };

    Posicion alineacion5[]=new Posicion[]{
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(-11.16030534351145,-35.78358208955224),
        new Posicion(12.717557251908397,-35.26119402985075),
        new Posicion(28.290076335877863,-28.470149253731343),
        new Posicion(-28.290076335877863,-28.470149253731343),
        new Posicion(14.793893129770993,-18.544776119402986),
        new Posicion(-17.389312977099234,-19.58955223880597),
        new Posicion(-23.618320610687025,-0.7835820895522387),
        new Posicion(5.969465648854961,-5.485074626865671),
        new Posicion(0.2595419847328244,-0.26119402985074625),
        new Posicion(22.580152671755727,-1.3059701492537314)
    };

    Posicion alineacion6[]=new Posicion[]{
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(-11.16030534351145,-35.78358208955224),
        new Posicion(12.717557251908397,-35.26119402985075),
        new Posicion(28.290076335877863,-28.470149253731343),
        new Posicion(-28.290076335877863,-28.470149253731343),
        new Posicion(14.793893129770993,-18.544776119402986),
        new Posicion(-17.389312977099234,-19.58955223880597),
        new Posicion(-23.618320610687025,-0.7835820895522387),
        new Posicion(6.4885496183206115,-6.529850746268657),
        new Posicion(-6.4885496183206115,-6.529850746268657),
        new Posicion(22.580152671755727,-1.3059701492537314)
    };

    Posicion ataqueNiupi[]= new Posicion[]{
      new Posicion(10.0, 10.0),
      new Posicion(-10.0, 15.0),
      new Posicion(10.0, 20.0),
      new Posicion(-10.0, 25.0),
      new Posicion(10.0, 30.0)
    };

    int ordenAvaliacao[][] = {
        /*0*/{1,3,6,7,9},
        /*1*/{4,5,6,8,9},
        /*2*/{6,5,4,8,9},
        /*4*/{8,6,9,10},
        /*5*/{7,6,9,10},
        /*6*/{9,10,8},
        /*7*/{9,10,8},
        /*8*/{9,10},
        /*9*/{8,10},
        /*10*/{9,8}
    };

    public class TacticaDetalleImpl implements TacticaDetalle {

        public String getNombre() {
            return "Jotitas";
        }

        public String getPais() {
            return "Peru";
        }

        public String getEntrenador() {
            return "Autori";
        }

        public Color getColorCamiseta() {
            return new Color(204, 0, 0);
        }

        public Color getColorPantalon() {
            return new Color(0, 0, 0);
        }

        public Color getColorFranja() {
            return new Color(255, 255, 255);
        }

        public Color getColorCalcetas() {
            return new Color(255, 255, 255);
        }

        public Color getColorPortero() {
            return new Color(0, 0, 255        );
        }

        public EstiloUniforme getEstilo() {
            return EstiloUniforme.SIN_ESTILO;
        }

        public Color getColorCamiseta2() {
            return new Color(255, 255, 255);
        }

        public Color getColorPantalon2() {
            return new Color(204, 0, 0);
        }

        public Color getColorFranja2() {
            return new Color(204, 0, 0);
        }

        public Color getColorCalcetas2() {
            return new Color(255, 255, 255);
        }

        public Color getColorPortero2() {
            return new Color(116, 165, 75        );
        }

        public EstiloUniforme getEstilo2() {
            return EstiloUniforme.FRANJA_DIAGONAL;
        }

        class JugadorImpl implements JugadorDetalle {

            String nombre;
            int numero;
            Color piel, pelo;
            double velocidad, remate, presicion;
            boolean portero;
            Posicion posicion;

            public JugadorImpl(String nombre, int numero, Color piel, Color pelo,
                    double velocidad, double remate, double presicion, boolean portero) {
                this.nombre=nombre;
                this.numero=numero;
                this.piel=piel;
                this.pelo=pelo;
                this.velocidad=velocidad;
                this.remate=remate;
                this.presicion=presicion;
                this.portero=portero;
            }

            public String getNombre() {
                return nombre;
            }

            public Color getColorPiel() {
                return piel;
            }

            public Color getColorPelo() {
                return pelo;
            }

            public int getNumero() {
                return numero;
            }

            public boolean esPortero() {
                return portero;
            }

            public double getVelocidad() {
                return velocidad;
            }

            public double getRemate() {
                return remate;
            }

            public double getPresicion() {
                return presicion;
            }

        }

        public JugadorDetalle[] getJugadores() {
            return new JugadorDetalle[]{
                new JugadorImpl("Goleiro", 1, new Color(255,200,150), new Color(50,0,0),1.0d,1.0d,0.5d, true),
                new JugadorImpl("Defensa", 2, new Color(255,200,150), new Color(50,0,0),1.0d,0.5d,0.5d, false),
                new JugadorImpl("Defensa", 3, new Color(255,200,150), new Color(50,0,0),1.0d,0.5d,0.5d, false),
                new JugadorImpl("Defensa", 4, new Color(255,200,150), new Color(50,0,0),1.0d,0.5d,0.5d, false),
                new JugadorImpl("Volante", 5, new Color(255,200,150), new Color(102,0,0),1.0d,0.5d,0.75d, false),
                new JugadorImpl("Volante", 6, new Color(255,200,150), new Color(50,0,0),1.0d,0.5d,0.75d, false),
                new JugadorImpl("MeioCampo", 7, new Color(255,200,150), new Color(50,0,0),1.0d,0.5d,1.0d, false),
                new JugadorImpl("MeioAtacante", 8, new Color(255,200,150), new Color(255,255,0),1.0d,1.0d,1.0d, false),
                new JugadorImpl("Atacante", 9, new Color(255,200,150), new Color(50,0,0),1.0d,1.0d,1.0d, false),
                new JugadorImpl("Atacante", 10, new Color(255,200,150), new Color(50,0,0),1.0d,1.0d,1.0d, false),
                new JugadorImpl("Atacante", 11, new Color(255,200,150), new Color(50,0,0),1.0d,1.0d,1.0d, false)
            };
        }
    }



    TacticaDetalle detalle=new TacticaDetalleImpl();
    public TacticaDetalle getDetalle() {
        return detalle;
    }

    public Posicion[] getPosicionSaca(SituacionPartido sp) {
    return alineacion5;
    }

    public Posicion[] getPosicionRecive(SituacionPartido sp) {
    return alineacion6;
    }

    public List<Comando> ejecutar(SituacionPartido sp) {
        Random r = new Random();

        //Limpia la listopta de comandos
        comandos.clear();
        //Obtiene las posiciones de tus jugadores
        Posicion[] jogadores = sp.misJugadores();
        Posicion[] rivais = sp.rivales();
        int[] meuAlcance = sp.iteracionesParaRematar();
        int[] rivalAlcance = sp.iteracionesParaRematarRival();
        JugadorDetalle[] meusDetalhes = sp.detalleMisJugadores();
        JugadorDetalle[] rivalDetalhes = sp.detalleJugadoresRivales();


        if( sp.balon().getX() < -9 ) {
            comandos.add( new ComandoIrA(0,
                    new Posicion( alineacion1[0].getX()-2, alineacion1[0].getY()) ) );
        } else if( sp.balon().getX() > 9 ) {
            comandos.add( new ComandoIrA(0,
                    new Posicion( alineacion1[0].getX()+2, alineacion1[0].getY()) ) );
        } else {
            comandos.add( new ComandoIrA(0, alineacion1[0]));
        }

        for(int i=1; i<jogadores.length; i++ ){
            double dist = NossoUtil.dist( jogadores[i], sp.balon() );
            if( dist > 50.0 ){
                comandos.add( new ComandoIrA(i,
                    new Posicion(
                    alineacion1[i].getX()+(sp.balon().getX() - jogadores[i].getX())*0.3 ,
                    alineacion1[i].getY()+(sp.balon().getY() - jogadores[i].getY())*0.3) )
                );
            }
            else if( dist>30 ) {
                comandos.add( new ComandoIrA(i,
                    new Posicion(
                    alineacion1[i].getX()+(sp.balon().getX() - jogadores[i].getX())*0.5 ,
                    alineacion1[i].getY()+(sp.balon().getY() - jogadores[i].getY())*0.5) )
                );

            } else if( dist>5 ) {

                comandos.add( new ComandoIrA(i,
                    new Posicion(
                    alineacion1[i].getX()+(sp.balon().getX() - jogadores[i].getX())*0.8 ,
                    alineacion1[i].getY()+(sp.balon().getY() - jogadores[i].getY())*0.8) )
                );
            }
        }


        //Se o rival nao joga bola de um lateral
        if (!sp.sacaRival()) {
            //Obtem os dados de recuperacao
            int[] recuperadores = sp.getRecuperacionBalon();
            //Se existe possibilidade de recuperar bola
            if (recuperadores.length > 1) {
                //Calcula a trajetoria do mais perto ate a bola
                double[] posRecuperacion = sp.getTrayectoria(recuperadores[0]);

                //Recorre la lista de jugadores que pueden recuperar
                for (int i = 1; i < recuperadores.length; i++) {
                    //Ordena a los jugadores recuperadores que se ubique
                    //en la posicion de recuperacion
                    comandos.add(new ComandoIrA(recuperadores[i],
                            new Posicion(posRecuperacion[0], posRecuperacion[1])));
                }
            }
        }


        for (int i : sp.puedenRematar()) {
            if( i==0 ){
                comandos.add( new ComandoGolpearBalon(i,jogadores[7],1,45));
            }
            else if( i>7 ) {
                if( NossoUtil.possoChutar(jogadores[i]) )
                    comandos.add( NossoUtil.chutarGol( i, meusDetalhes[i].getPresicion(), meusDetalhes[i].getVelocidad(), jogadores[i], rivais ));
                else {
                    comandos.add( new ComandoGolpearBalon(i,Constantes.centroArcoSup,0.35,true));
                    comandos.add( new ComandoIrA(i, Constantes.centroArcoSup ));
                }
            }
            else if( i< 8 ) {
                Comando  cmd = NossoUtil.tocarAoProximo( i, jogadores, rivais, ordenAvaliacao );
                if( cmd != null )
                    comandos.add( cmd );
                else
                    comandos.add( new ComandoGolpearBalon(
                            i,
                            Constantes.centroArcoSup,
                            1.0,
                            NossoUtil.elevacao(meusDetalhes[i].getVelocidad())
                            ));
            }
        }

        for( int i : sp.puedenRematarRival() ){
            if( i>0 ){
                Posicion alcance = new Posicion(
                        (sp.balon().getX()+Constantes.centroArcoSup.getX())/2,
                        (sp.balon().getY()+Constantes.centroArcoSup.getY()));
                comandos.add ( new ComandoIrA( NossoUtil.getProximoJogador(alcance, jogadores), alcance));
            }
        }



        //Retorna la lista de comandos
        return comandos;
    }

}